package com.iss.supermarket.LoginUI;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

public class VerificationCodeGenerator {
    //单例模式
    private static VerificationCodeGenerator verificationCodeGenerator;
    //定义组件
    private BufferedImage image;
    private Random random = new Random();
    private Color backgroundColor;
    private Color lineColor;
    private Color foreColor;
    private String VerificationCode;
    private static final String exChars = "01234567890123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public String getRandomCode(int length,String exChars){
        //生成验证码
        int i=0;

        StringBuffer stringBuffer = new StringBuffer();
        char[] chars = exChars.toCharArray();

        while(i<length){
            int t=random.nextInt(72);
            stringBuffer.append(chars[t]);
            ++i;
        }

        return stringBuffer.toString();
    }

    private Color getRandomColor(){
        //生成随机色彩
        int r = random.nextInt(255);
        int g = random.nextInt(255);
        int b = random.nextInt(255);
        Color returncolor = new Color(r,g,b);
        return returncolor;
    }

    public BufferedImage createImage(int width, int height, int linecount){
        //创建BufferedImage对象
        image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        VerificationCode = getRandomCode(4,exChars);
        //创建Graphics对象
        Graphics graphics = image.getGraphics();
        boolean randomLocation = true;

        graphics.setColor(backgroundColor==null?getRandomColor():backgroundColor);
        graphics.fillRect(0,0,width,height);

        //绘制干扰线
        if(linecount > 0){
            int x = random.nextInt(4);
            int y = 0;
            int x1 = width- random.nextInt(4);
            int y1 = 0;
            for(int i=0;i<linecount;++i){
                graphics.setColor(lineColor == null?getRandomColor():lineColor);
                y = random.nextInt(height- random.nextInt(4));
                y1 = random.nextInt(height- random.nextInt(4));
                graphics.drawLine(x,y,x1,y1);
            }
        }

        //绘制验证码
        int fsize = (int)(height*0.8);
        int fx = 0;
        int fy = fsize;
        graphics.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,fsize));
        for(int i=0;i<VerificationCode.length();++i){
            fy = randomLocation?(int)((Math.random()*0.3+0.6)*height):fy;
            graphics.setColor(foreColor==null?getRandomColor():foreColor);
            graphics.drawString(VerificationCode.charAt(i)+"",fx,fy);
            fx += (width/VerificationCode.length()) * (Math.random() * 0.3 + 0.8);
        }

        //将图片水平和垂直按不同比例平移
        shearX(graphics,width,height,backgroundColor);
        shearY(graphics,width,height,backgroundColor);

        //添加噪点
        float yawpRate = 0.05f;// 噪声率
        int area = (int) (yawpRate * width * height);//噪点数量
        for (int i = 0; i < area; i++) {
            int xxx = random.nextInt(width);
            int yyy = random.nextInt(height);
            int rgb = getRandomColor().getRGB();
            image.setRGB(xxx, yyy, rgb);
        }

        //关闭Graphics
        graphics.dispose();
        return image;
    }

    private void shearX(Graphics g,int w1,int h1,Color color){
        int period = 2;

        boolean borderGap = true;
        int frames = 1;
        int phase = random.nextInt(2);

        for(int i=0;i<h1;++i){
            double d = (double)(period >> i) * Math.sin((double)i/(double)period+(2.2831853071795862D * (double) phase)/ (double) frames);
            g.copyArea(0,i,w1,1,(int)d,0);
            if(borderGap){
                g.setColor(color);
                g.drawLine(i,(int)d,i,0);
                g.drawLine(i,(int)d+h1,i,h1);
            }
        }
    }

    private void shearY(Graphics g, int w1, int h1, Color color) {
        Random random=new Random();
        int period = random.nextInt(40) + 10;
        boolean borderGap = true;
        int frames = 20;
        int phase = random.nextInt(2);
        for (int i = 0; i < w1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (2.2831853071795862D * (double) phase)/ (double) frames);
            g.copyArea(i, 0, 1, h1, 0, (int) d);
            if (borderGap) {
                g.setColor(color);
                g.drawLine(i, (int) d, i, 0);
                g.drawLine(i, (int) d + h1, i, h1);
            }
        }
    }

    //通过输出六保存img
//    public static void main(String[] args) {
//        VerificationCodeGenerator verificationCodeGenerator = VerificationCodeGenerator.getVerificationCodeGenerator();
//        String randomCode = verificationCodeGenerator.getVerificationCode();
//        System.out.println(randomCode);
//        BufferedImage imageFromCode = verificationCodeGenerator.createImage(100,50,3);
//        try {
//            File file = new File("d:/test01.jpg");
//            ImageIO.write(imageFromCode,"jpg",file);
//            System.out.println("成功保存到："+file.getAbsolutePath());
//        } catch (IOException e) {
//            System.out.println("保存失败");
//            e.printStackTrace();
//        }
//    }

    public String getVerificationCode() {
        return VerificationCode;
    }

    public static synchronized VerificationCodeGenerator getVerificationCodeGenerator(){
        if(verificationCodeGenerator == null){
            verificationCodeGenerator = new VerificationCodeGenerator();
        }
        return verificationCodeGenerator;
    }

}